package org.web.standardplatform.client.helper.view.rules;

import java.util.*;

/**
 * 构建 TypeScript 的数组对象定义（仅输出数组结构，不带变量名与类型）。
 */
public class TsObjectArrayBuilder {

    public static TsObjectArrayBuilder create() {
        return new TsObjectArrayBuilder();
    }

    private final List<Map<String, FieldValue>> items = new ArrayList<>();

    private TsObjectArrayBuilder() {
        // 不需要 variableName 和 typeName
    }

    public ItemBuilder addItem() {
        return new ItemBuilder(this);
    }

    public List<Map<String, FieldValue>> getItems() {
        return Collections.unmodifiableList(items);
    }

    public String build() {
        StringBuilder sb = new StringBuilder();
        sb.append("[\n");

        for (int i = 0; i < items.size(); i++) {
            sb.append("  {\n");
            Map<String, FieldValue> item = items.get(i);
            int count = 0;
            for (Map.Entry<String, FieldValue> entry : item.entrySet()) {
                sb.append("    ").append(entry.getKey()).append(": ");
                sb.append(entry.getValue().render());
                count++;
                if (count < item.size()) {
                    sb.append(",");
                }
                sb.append("\n");
            }
            sb.append("  }");
            if (i < items.size() - 1) {
                sb.append(",");
            }
            sb.append("\n");
        }

        sb.append("];\n");
        return sb.toString();
    }

    public String buildAsField(String fieldName) {
        StringBuilder sb = new StringBuilder();
        sb.append(fieldName).append(": [\n");

        for (int i = 0; i < items.size(); i++) {
            sb.append("  {\n");
            Map<String, FieldValue> item = items.get(i);
            int count = 0;
            for (Map.Entry<String, FieldValue> entry : item.entrySet()) {
                sb.append("    ").append(entry.getKey()).append(": ");
                sb.append(entry.getValue().render());
                count++;
                if (count < item.size()) {
                    sb.append(",");
                }
                sb.append("\n");
            }
            sb.append("  }");
            if (i < items.size() - 1) {
                sb.append(",");
            }
            sb.append("\n");
        }

        sb.append("],");
        return sb.toString();
    }

    public static class ItemBuilder {
        private final Map<String, FieldValue> fieldMap = new LinkedHashMap<>();
        private final TsObjectArrayBuilder parent;

        private ItemBuilder(TsObjectArrayBuilder parent) {
            this.parent = parent;
        }

        public ItemBuilder field(String key, Object value) {
            return field(key, value, false);
        }

        public ItemBuilder field(String key, Object value, boolean raw) {
            if (raw && value instanceof String) {
                fieldMap.put(key, new FieldValue((String) value, true));
            } else {
                fieldMap.put(key, new FieldValue(value));
            }
            return this;
        }

        public TsObjectArrayBuilder end() {
            parent.items.add(fieldMap);
            return parent;
        }
    }

    private static class FieldValue {
        private final Object value;
        private final boolean raw;

        FieldValue(Object value) {
            this.value = value;
            this.raw = false;
        }

        FieldValue(String rawValue, boolean raw) {
            this.value = rawValue;
            this.raw = raw;
        }

        String render() {
            if (raw) return value.toString();
            if (value == null) return "null";
            if (value instanceof String) return "'" + escape((String) value) + "'";
            if (value instanceof Boolean || value instanceof Number) return value.toString();
            return "'" + escape(value.toString()) + "'";
        }

        private String escape(String str) {
            return str.replace("\\", "\\\\").replace("'", "\\'");
        }
    }

    public static String formatTsObject(String input) {
        try {
            String[] lines = input.split("\n");
            StringBuilder formatted = new StringBuilder();
            int indent = 0;
            for (String line : lines) {
                line = line.trim();
                if (line.endsWith("},") || line.endsWith("}")) {
                    indent--;
                }
                for (int i = 0; i < indent; i++) {
                    formatted.append("  ");
                }
                formatted.append(line).append("\n");
                if (line.endsWith("{") || line.endsWith("[")) {
                    indent++;
                }
            }
            return formatted.toString();
        } catch (Exception e) {
            return input;
        }
    }
}
